package com.zbkj.crmeb.payment.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.constants.Constants;
import com.crmeb.core.exception.CrmebException;
import com.utils.DateUtil;
import com.zbkj.crmeb.marketing.request.StoreCouponUserRequest;
import com.zbkj.crmeb.marketing.service.StoreCouponUserService;
import com.zbkj.crmeb.payment.service.OrderPayService;
import com.zbkj.crmeb.payment.service.PayService;
import com.zbkj.crmeb.payment.service.RefundPayService;
import com.zbkj.crmeb.payment.vo.wechat.CreateOrderResponseVo;
import com.zbkj.crmeb.payment.vo.wechat.PayParamsVo;
import com.zbkj.crmeb.payment.wechat.WeChatPayService;
import com.zbkj.crmeb.sms.service.SmsService;
import com.zbkj.crmeb.store.model.StoreOrder;
import com.zbkj.crmeb.store.model.StoreProductCoupon;
import com.zbkj.crmeb.store.request.RetailShopRequest;
import com.zbkj.crmeb.store.service.*;
import com.zbkj.crmeb.store.vo.StoreOrderInfoVo;
import com.zbkj.crmeb.user.model.User;
import com.zbkj.crmeb.user.model.UserBill;
import com.zbkj.crmeb.user.service.UserBillService;
import com.zbkj.crmeb.user.service.UserService;
import com.zbkj.crmeb.wechat.service.TemplateMessageService;
import com.zbkj.crmeb.wechat.service.WeChatService;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;


/**
 * <p>
 * 支付类
 * </p>
 *
 * @author Mr.Zhang
 * @since 2020-04-10
 */
@EqualsAndHashCode(callSuper = true)
@Data
@Service
public class RefundPayServiceImpl extends PayService implements RefundPayService {
    private static final Logger logger = LoggerFactory.getLogger(RefundPayServiceImpl.class);

    @Autowired
    private StoreOrderService storeOrderService;

    @Autowired
    private StoreOrderStatusService storeOrderStatusService;

    @Autowired
    private StoreOrderInfoService storeOrderInfoService;

    @Lazy
    @Autowired
    private WeChatPayService weChatPayService;

    @Autowired
    private TemplateMessageService templateMessageService;

    @Autowired
    private UserBillService userBillService;

    @Lazy
    @Autowired
    private SmsService smsService;

    @Autowired
    private UserService userService;

    @Autowired
    private StoreProductCouponService storeProductCouponService;

    @Autowired
    private StoreCouponUserService storeCouponUserService;

    @Autowired
    private WeChatService weChatService;

    //订单类
    private StoreOrder order;

    //支付类参参数
    private PayParamsVo payParamsVo;

    @Autowired
    private RetailShopService retailShopService;

    @Autowired
    private OrderPayService orderPayService;



    /**
     * 支付之前
     * @author Mr.Zhang
     * @since 2020-06-22
     */
    private void beforePay() {
        checkOrderUnPay();
    }


    @Override
    public CreateOrderResponseVo payOrder(Integer orderId, String fromType, String clientIp) {
        return null;
    }

    /**
     * 支付成功
     * @param orderId String 订单号
     * @param userId Integer 用户id
     * @param payType String 支付类型
     * @author Mr.Zhang
     * @since 2020-06-22
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Error.class, CrmebException.class})
    public boolean success(String orderId, Integer userId, String payType,String outOrderId, String backParam) {
        try{
            StoreOrder storeOrder = new StoreOrder();
            storeOrder.setOrderId(orderId);
            storeOrder.setUid(userId);

            storeOrder = storeOrderService.getInfoByEntity(storeOrder);
            setOrder(storeOrder);
            checkOrderUnPay();

            afterPaySuccess(getOrder());
            return true;
        }catch (Exception e){
            throw new CrmebException("订单支付回调失败，" + e.getMessage());
        }
    }


    /**
     * 支付成功之后, 需要事物处理
     * @author Mr.Zhang
     * @since 2020-06-22
     * @return
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Error.class, CrmebException.class})
    public void afterPaySuccess(StoreOrder storeOrder){
        //更新订单状态
        orderUpdate(storeOrder);

        //订单日志
        orderStatusCreate(storeOrder);

        //返佣订单生成
        userBillCreate(storeOrder);

        //下发模板通知
        pushTempMessage(storeOrder);

        //购买成功后根据配置送优惠券
        autoSendCoupons(storeOrder);

        //更新用户下单数量
        updateUserPayCount(storeOrder);

        //增加经验、积分
        updateFounds(storeOrder);
    }



    /**
     * 支付成功之后 - 更新订单状态
     * @author Mr.Zhang
     * @since 2020-07-01
     */
    private void orderUpdate(StoreOrder storeOrder) {
        try {
            //修改订单状态
            StoreOrder storeOrderUpdate = new StoreOrder();
            storeOrderUpdate.setOrderId(storeOrder.getOrderId());
            storeOrderUpdate.setId(storeOrder.getId());
            storeOrderUpdate.setPaid(true);
            storeOrderUpdate.setPayType(storeOrder.getPayType());
            storeOrderUpdate.setPayTime(DateUtil.nowDateTime());
            if (!storeOrderService.updateById(storeOrderUpdate)) {
                throw new CrmebException("操作失败");
            }
        }catch (Exception e){
            throw new CrmebException("更新订单状态异常" + e);
        }
    }

    /**
     * 支付成功之后 - 订单日志(添加订单支付记录)
     * @author Mr.Zhang
     * @since 2020-07-01
     */
    private void orderStatusCreate(StoreOrder storeOrder) {
        storeOrderStatusService.createLog(storeOrder.getId(),storeOrder.getOrderId(), Constants.ORDER_LOG_PAY_SUCCESS, Constants.ORDER_LOG_MESSAGE_PAY_SUCCESS);
    }

    /**
     * 支付成功之后 - 返佣订单生成
     * @param storeOrder
     */
    private void userBillCreate(StoreOrder storeOrder) {
       try {
            Integer fristSpreadUid = null;
            Integer secondSpreadUid = null;

            //当前下单用户的信息
            Integer uid = storeOrder.getUid();
            User user = userService.getById(uid);

            //一级推广人:当前下单用户的推广人
            if (ObjectUtils.isNotEmpty(user)){
                fristSpreadUid = user.getSpreadUid();
            }

            //二级推广人:一级推广人的推广人
            if (null != fristSpreadUid){
                User secondUser = userService.getById(fristSpreadUid);
                if (ObjectUtils.isNotEmpty(secondUser)){
                    secondSpreadUid = secondUser.getSpreadUid();
                }
            }

            //获取分销配置
            RetailShopRequest retailShop = retailShopService.getManageInfo();

            //一级返佣比例
            String storeBrokerageRatio = retailShop.getStoreBrokerageRatio();

            //二级返佣比例
            String storeBrokerageTwo = retailShop.getStoreBrokerageTwo();

            //冻结天数
            String extractTime =  retailShop.getExtractTime();

            //一级推广人返佣订单生成
            createStoreBrokerage(fristSpreadUid, storeBrokerageRatio, extractTime, storeOrder);

            //二级推广人返佣订单生成
            createStoreBrokerage(secondSpreadUid, storeBrokerageTwo, extractTime, storeOrder);
        }catch (Exception e){
            throw new CrmebException("返佣订单生成异常" + e);
        }
    }

    /**
     * 返佣订单生成
     * @param spreadUid
     * @param brokerageRatio
     */
    private void createStoreBrokerage(Integer spreadUid, String brokerageRatio, String extractTime, StoreOrder storeOrder) {
        if (null != spreadUid){

            //冻结时间 = 当前时间 + 冻结天数
            Date freezeTime = DateUtil.nowDateTime();
            if (StringUtils.isNotBlank(extractTime)&& NumberUtils.isDigits(extractTime)){
                freezeTime = DateUtils.addDays(DateUtil.nowDateTime(),Integer.parseInt(extractTime));
            }

            //返佣比例
            BigDecimal storeBrokerageRatioDec = new BigDecimal(0);
            if (StringUtils.isNotBlank(brokerageRatio)){
                storeBrokerageRatioDec = new BigDecimal(brokerageRatio).multiply(new BigDecimal(0.01).setScale(2,BigDecimal.ROUND_HALF_DOWN));
            }

            //支付金额
            BigDecimal payPrice = storeOrder.getPayPrice();
            //运费
            BigDecimal payPostage = storeOrder.getPayPostage();
            //商品金额
            BigDecimal productPrice = payPrice.subtract(payPostage);

            //佣金 = 商品金额 * 返佣比例
            if (null != productPrice&& null != storeBrokerageRatioDec) {
                BigDecimal number = productPrice.multiply(storeBrokerageRatioDec);
                addUserBill(spreadUid, number, freezeTime, storeOrder);
            }

        }
    }

    /**
     * 生成用户推广订单
     */
    private void addUserBill(Integer uid, BigDecimal number, Date freezeTime, StoreOrder storeOrder) {
        UserBill userBill = new UserBill();
        userBill.setUid(uid);
        userBill.setPm(0);
        userBill.setLinkId(storeOrder.getId().toString());
        userBill.setTitle("购买商品");
        userBill.setCategory(Constants.USER_BILL_CATEGORY_BROKERAGE_PRICE);
        userBill.setType(Constants.USER_BILL_TYPE_PAY_PRODUCT);
        userBill.setFreezeTime(freezeTime);
        userBill.setMark("支付" + storeOrder.getPayPrice() + "元购买商品");
        //佣金
        userBill.setNumber(number);
        //余额
        userBill.setBalance(userService.getById(storeOrder.getUid()).getNowMoney());
        userBillService.save(userBill);
    }

    /**
     * 支付成功之后 - 发送模板消息通知
     * @author Mr.Zhang
     * @since 2020-07-01
     */
    private void pushTempMessage(StoreOrder storeOrder) {
        String tempKey = Constants.WE_CHAT_PUBLIC_TEMP_KEY_ORDER_PAY_SUCCESS;
        String type = Constants.PAY_TYPE_WE_CHAT_FROM_PUBLIC;
        if(Constants.ORDER_PAY_CHANNEL_PROGRAM == storeOrder.getIsChannel()){
            tempKey = Constants.WE_CHAT_PROGRAM_TEMP_KEY_ORDER_PAY_SUCCESS;
            type = Constants.PAY_TYPE_WE_CHAT_FROM_PROGRAM;
        }

        HashMap<String, String> map = new HashMap<>();
        map.put(Constants.WE_CHAT_TEMP_KEY_FIRST, "订单支付成功");
        map.put("orderId", storeOrder.getOrderId());
        map.put("payAmount", storeOrder.getPayPrice().toString());
        map.put(Constants.WE_CHAT_TEMP_KEY_END, "感谢购买！");

        templateMessageService.push(tempKey, map, storeOrder.getUid(), type);
    }

    /**
     * 支付成功之后 - 商品购买后根据配置送券
     * @param storeOrder
     */
    private void autoSendCoupons(StoreOrder storeOrder){
        // 根据订单详情获取商品信息
//        List<StoreOrderInfoVo> orders = storeOrderInfoService.getOrderListByOrderId(storeOrder.getId());
//        if(null == orders){
//            return;
//        }
//        for (StoreOrderInfoVo order : orders) {
//            List<StoreProductCoupon> couponsForGiveUser = storeProductCouponService.getListByProductId(order.getProductId());
//            if(CollectionUtils.isNotEmpty(couponsForGiveUser)) {
//                for (StoreProductCoupon storeProductCoupon : couponsForGiveUser) {
//                    StoreCouponUserRequest crp = new StoreCouponUserRequest();
//                    crp.setUid(storeOrder.getUid() + "");
//                    crp.setCouponId(storeProductCoupon.getIssueCouponId());
//                    storeCouponUserService.receive(crp);
//                }
//            }
//        }
    }

    /**
     * 支付成功之后 - 更新用户下单数量
     */
    private void updateUserPayCount(StoreOrder storeOrder) {
        userService.userPayCountPlus(userService.getById(storeOrder.getUid()));
    }


    /**
     * 支付成功之后 - 更新用户积分经验
     */
    private void updateFounds(StoreOrder storeOrder) {
        userService.consumeAfterUpdateUserFounds(storeOrder.getUid(), storeOrder.getId().toString(), storeOrder.getPayPrice(), Constants.USER_BILL_TYPE_PAY_ORDER);
    }

    /**
     * 检测是否未支付
     * @author Mr.Zhang
     * @since 2020-06-22
     */
    private void checkOrderUnPay() {
        if(null == getOrder()){
            throw new CrmebException("没有找到订单信息");
        }

        if(getOrder().getPaid()){
            throw new CrmebException("当前操作被禁止，订单已经被处理");
        }
    }

    /**
     * 获取订单详情数据
     * @author Mr.Zhang
     * @since 2020-06-22
     * @return List<StoreOrderInfoVo>
     */
    private List<StoreOrderInfoVo> getStoreOrderInfoList(){
        //商品信息
        return storeOrderInfoService.getOrderListByOrderId(getOrder().getId());
    }

    /**
     * 获取订单产品名称
     * @author Mr.Zhang
     * @since 2020-06-22
     * @return String
     */
    private String getProductName(){

        List<StoreOrderInfoVo> orderList = getStoreOrderInfoList();
        if(orderList.size() < 1){
            throw new CrmebException("在订单里没有找到商品数据");
        }
//        return orderList.get(0).getInfo().getJSONObject("productInfo").getString("store_name");
        return orderList.get(0).getInfo().getProductInfo().getStoreName();
    }
}
